package Server;

import Data.FileData;
import Data.MassageData;
import Data.event;
import MyInterfaces.MassageType;
import com.mysql.cj.jdbc.result.ResultSetImpl;

import java.io.*;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;

public class GetFile {

    private MassageData massageData;

    private String path="E:\\JDK\\QQServer\\nox\\src\\File";
    String url = "jdbc:mysql://127.0.0.1:3306/nox?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8";
    String user = "root";
    String password = "Mi20030610.";

    public GetFile(MassageData massageData) {

        this.massageData = massageData;
    }

    public MassageData getFile() throws IOException, ClassNotFoundException, SQLException, NoSuchAlgorithmException {

        //先在判断数据库是否已经有了
        String searchsql="select *from file where MD5=? and suffix_name=?;";
        Connection Conn = DriverManager.getConnection(url, user, password);
        PreparedStatement operation = null;
        operation=Conn.prepareStatement(searchsql);
        operation.setString(1,massageData.getMD5());
        operation.setString(2,massageData.getSuffix_name());

        ResultSet resultSet=operation.executeQuery();

        if(resultSet.next())
        {
            System.out.println("已经存在");
            String id=resultSet.getString("id");
            //需要返回一个文件消息
            massageData.setFile_id(id);

            //说明已经有了，不需要往里面插入，需要插入消息记录
            String sql = "insert into massagelist (sender_id,receiver_id,date,is_file,file_name,file_id) VALUES(?,?,?,?,?,?);";
            resultSet.close();
            operation.close();
            PreparedStatement op1=Conn.prepareStatement(sql);
            op1=Conn.prepareStatement(sql);
            op1.setString(1, massageData.getSender());
            op1.setString(2, massageData.getReceiver());
            op1.setTimestamp(3, massageData.getTimestamp());
            op1.setInt(4, 1);
            op1.setString(5, massageData.getFile_name());
            op1.setString(6, id);
            int k=op1.executeUpdate();
            op1.close();

            return massageData;
        }
        else
        {
            System.out.println("遇到没有出现过的文件");
            operation.close();
            //说明文件里面没有
            String newdate=massageData.getTimestamp().toString().replace(":","_");
            path = "F:\\qqserverfile\\file" + "\\" + massageData.getSender() + "to" + massageData.getReceiver() +" "+ newdate + "." + massageData.getSuffix_name();
            String sqlpath = path.replace("\\", "\\\\");
            System.out.println(path);
            File file = new File(path);
            System.out.println(file.getAbsolutePath());

            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(massageData.getBytes());
            fileOutputStream.close();
            if (!getMD5(file).equals(massageData.getMD5()) ) {
                //文件读取出错
                System.out.println("MD5值不一样");
                massageData.setMD5(null);
                file.delete();
                return massageData;
            }

            String sql = "insert into massagelist (sender_id,receiver_id,date,is_file,file_name,file_id) VALUES(?,?,?,?,?,?);";
            PreparedStatement op1=Conn.prepareStatement(sql);
            System.out.println(sql);
            op1.setString(1, massageData.getSender());
            op1.setString(2, massageData.getReceiver());
            op1.setTimestamp(3, massageData.getTimestamp());
            op1.setInt(4, 1);
            op1.setString(5, massageData.getFile_name());
            op1.setString(6, massageData.getSender() + "to" + massageData.getReceiver()+ massageData.getTimestamp());
            int k = op1.executeUpdate();
            op1.close();
            System.out.println(k);
            if (k > 0) {
                System.out.println("插入到数据库里面代表我已经有了");
                String newsql = "INSERT INTO file (file_name,file_path,id,MD5,suffix_name) VAlUES (?,?,?,?,?);";
                PreparedStatement op2=null;
                op2 = Conn.prepareStatement(newsql);
                op2.setString(1, massageData.getFile_name());
                op2.setString(2, sqlpath);
                op2.setString(3, massageData.getSender() + "to" + massageData.getReceiver()  + massageData.getTimestamp());
                op2.setString(4,massageData.getMD5());
                op2.setString(5,massageData.getSuffix_name());

                int y=op2.executeUpdate();

                op2.close();
                Conn.close();
                System.out.println("写入成功");

                massageData.setFile_id(massageData.getSender() + "to" + massageData.getReceiver()+ massageData.getTimestamp());
                return massageData;
            }
            else
            {
                System.out.println("写入失败");
                operation.close();
                Conn.close();
                massageData.setMD5(null);
                return massageData;
            }
        }

//
//
//
//        path = "E:\\JDK\\QQServer\\nox\\src\\File" + "\\" + fileData.getSender() + "to" + fileData.getReceiver() +" "+ newdate + "." + fileData.getSuffix_name();
//        String sqlpath = path.replace("\\", "\\\\");
//        System.out.println(path);
//        File file = new File(path);
//        System.out.println(file.getAbsolutePath());
//
//        FileOutputStream fileOutputStream = new FileOutputStream(file);
//        fileOutputStream.write(fileData.getBytes());
//        fileOutputStream.close();
//        if (!getMD5(file).equals(fileData.getMD5()) ) {
//            //文件读取出错
//            System.out.println("MD5值不一样");
//            return false;
//        }
//
//        Connection Conn = DriverManager.getConnection(url, user, password);
//        PreparedStatement operation = null;
//
//        operation = Conn.prepareStatement(sql);
//        System.out.println(sql);
//        operation.setString(1, fileData.getSender());
//        operation.setString(2, fileData.getReceiver());
//        operation.setTimestamp(3, fileData.getTimestamp());
//        operation.setInt(4, 1);
//        operation.setString(5, fileData.getFile_name());
//        operation.setString(6, fileData.getSender() + "to" + fileData.getReceiver()+ fileData.getTimestamp());
//
//        int k = operation.executeUpdate();
//        System.out.println(k);
//        if (k > 0) {
//            String newsql = "INSERT INTO file (file_name,file_path,id) VAlUES (?,?,?);";
//            operation = null;
//            operation = Conn.prepareStatement(newsql);
//            operation.setString(1, fileData.getFile_name());
//            operation.setString(2, sqlpath);
//            operation.setString(3, fileData.getSender() + "to" + fileData.getReceiver() + " " + fileData.getTimestamp());
//
//            operation.close();
//            Conn.close();
//            System.out.println("写入成功");
//            return true;
//        } else {
//            System.out.println("写入失败");
//            operation.close();
//            Conn.close();
//            return false;
//        }



//        path=path+"\\"+fileData.getSender()+" to "+fileData.getReceiver()+new Date().toString()+"."+fileData.getSuffix_name();
//        System.out.println(path);
//        File file=new File(path);
//        System.out.println("准备文件");
//        HashMap<Integer,byte[]> newfile = new HashMap<>();
//        System.out.println("目前可以");
//
//    //    System.out.println("不可以");
//        long timeoutMillis=file.length();
//        long startTime=System.currentTimeMillis();
//        int count=0;
//        System.out.println("进去");
//        while(true)
//        {
//            System.out.println("倒计时开始");
//            int available=socket.getInputStream().available();
//            System.out.println(socket.toString());
//            if(available>0) {
//           //     socket=ManageClientConnectionServerThread.getSocketByUserid()
//
//                ObjectInputStream reader=new ObjectInputStream(socket.getInputStream());
//                event massage = (event) reader.readObject();
//                System.out.println("好像阻塞了");
//                if (massage.getType().equals(MassageType.Send_File)) {
//                    FileData data = (FileData) massage.getT();
//                    int index = data.getIndex();
//                    byte[] bytes = data.getBytes();
//                    newfile.put(index, bytes);
//                    count++;
//                    System.out.println(index);
//                }
//                if (count >= fileData.getTotalbytes()) break;
//            }
//            long now=System.currentTimeMillis();
//            System.out.println(now);
//            if(now-startTime>timeoutMillis) break;
//        }
//        FileOutputStream fos=new FileOutputStream(file);
//        for (int i = 0; i < fileData.getTotalbytes(); i++)
//        {
//            if(!newfile.containsKey(i))
//            {
//                return false;
//            }
//            fos.write(newfile.get(i));
//            System.out.println("接收到了第"+i+"个，一共有"+fileData.getTotalbytes()+"个");
//        }
//        fos.close();
//        try {
//            if(getMD5(file)!=fileData.getMd5()) return false;
//        } catch (NoSuchAlgorithmException e) {
//            throw new RuntimeException(e);
//        }
//        return true;
    }

    public static String getMD5(File file) throws IOException, NoSuchAlgorithmException
    {
        InputStream inputStream = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        int numRead = 0;
        while ((numRead = inputStream.read(buffer)) > 0) {
            md5.update(buffer, 0, numRead);
        }
        inputStream.close();
        byte[] md5Bytes = md5.digest();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < md5Bytes.length; i++) {
            if (Integer.toHexString(0xFF & md5Bytes[i]).length() == 1) {
                sb.append("0").append(Integer.toHexString(0xFF & md5Bytes[i]));
            } else {
                sb.append(Integer.toHexString(0xFF & md5Bytes[i]));
            }
        }
        return sb.toString();
    }
}
